package controller;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import model.Snake;

import common.Direction;

/**
 * Attach a key listener.  When a key is pressed check if it is in the map
 * of keys we are interested in and if it is, notify the snake of the update */
public class KeyController extends KeyAdapter {
	
	private String newline = "\n";
	private Map<Snake, Map<Direction, Integer>> snakesAndKeys = 
		new HashMap<Snake, Map<Direction,Integer>>();
	
	public void addSnakeKeyMapping(Snake snakeToMap, Map<Direction, Integer> keyToDirection) {
		snakesAndKeys.put(snakeToMap, keyToDirection);
	}
	
	public Map<Direction, Integer> removeSnakeKeyMapping(Snake snakeToRemove) {
		return snakesAndKeys.remove(snakeToRemove);
	}
 	
	@Override
	public void keyPressed(KeyEvent e) {
		displayInfo(e, "KEY PRESSED: ");
		moveSnakeOnMappedKey(e);
	}
	
	private void moveSnakeOnMappedKey(KeyEvent e) {
		for (Snake snake : snakesAndKeys.keySet()) {
			Map<Direction, Integer> keys = snakesAndKeys.get(snake);
			for (Entry<Direction, Integer> mapping : keys.entrySet()) {
				if (mapping.getValue().equals(e.getKeyCode())) {
					snake.changeDirection(mapping.getKey());
					break;
				}
			}
		}
	}

	/*
     * We have to jump through some hoops to avoid
     * trying to print non-printing characters
     * such as Shift.  (Not only do they not print,
     * but if you put them in a String, the characters
     * afterward won't show up in the text area.)
     */
    private void displayInfo(KeyEvent e, String keyStatus){
        
        //You should only rely on the key char if the event
        //is a key typed event.
        int id = e.getID();
        String keyString;
        if (id == KeyEvent.KEY_TYPED) {
            char c = e.getKeyChar();
            keyString = "key character = '" + c + "'";
        } else {
            int keyCode = e.getKeyCode();
            keyString = "key code = " + keyCode
                    + " ("
                    + KeyEvent.getKeyText(keyCode)
                    + ")";
        }
        
        int modifiersEx = e.getModifiersEx();
        String modString = "extended modifiers = " + modifiersEx;
        String tmpString = KeyEvent.getModifiersExText(modifiersEx);
        if (tmpString.length() > 0) {
            modString += " (" + tmpString + ")";
        } else {
            modString += " (no extended modifiers)";
        }
        
        String actionString = "action key? ";
        if (e.isActionKey()) {
            actionString += "YES";
        } else {
            actionString += "NO";
        }
        
        String locationString = "key location: ";
        int location = e.getKeyLocation();
        if (location == KeyEvent.KEY_LOCATION_STANDARD) {
            locationString += "standard";
        } else if (location == KeyEvent.KEY_LOCATION_LEFT) {
            locationString += "left";
        } else if (location == KeyEvent.KEY_LOCATION_RIGHT) {
            locationString += "right";
        } else if (location == KeyEvent.KEY_LOCATION_NUMPAD) {
            locationString += "numpad";
        } else { // (location == KeyEvent.KEY_LOCATION_UNKNOWN)
            locationString += "unknown";
        }
        
        System.out.println(keyStatus + newline 
                + "    " + keyString + newline
                + "    " + modString + newline
                + "    " + actionString + newline
                + "    " + locationString + newline);
    }

}
